﻿// Rice.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include"opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include"opencv2/xfeatures2d.hpp"
using namespace cv;
using namespace std;

int main()
{
	Mat img = imread("F:\\AI\\Course\\Chapter3\\rice.jpg");
	//Mat img = imread("E:\\picture\\Lena.jpg");
	Mat gray, bw;
	int g_nStructElementSize = 3,count = 0;
	string strCount;
	double len;
	float area; // 定义浮点型area变量用以存放单一Blob外围边缘所围面积
	Rect rect;
    //转换到灰度图像
	cvtColor(img, gray, COLOR_BGR2GRAY);
	//进行大津算法
	threshold(gray, bw, 0, 0xff, CV_THRESH_OTSU);
	//imshow("大津算法分割后图片", bw);

	Mat element = getStructuringElement(MORPH_CROSS, Size(g_nStructElementSize, g_nStructElementSize));//这一步是获取图像形状和尺寸的结构元素（3*3十字叉形核）
	morphologyEx(bw, bw, MORPH_OPEN, element);//进行开运算，去除图中一些小亮点

	//进行图像分割
	Mat seg = bw.clone();
	vector<vector<Point>> cnts;//定义二维vector的点
	findContours(seg, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);// 调用findContours()函数对掩膜复制图像seg中的Blob进行检测，检测方式是忽略内部边缘仅识别外部边缘

	//进行筛选
	for (int i = cnts.size() - 1; i >= 0; i--)
	{
		vector<Point> c = cnts[i];
		len = arcLength(c, true);// 调用arcLength()函数计算该单一Blob长度
		area = contourArea(c); //调用contourArea()函数计算该单一Blob外围边缘所围面积
		if (area < 10)
			continue;
		area += area;
		len += len;
		count++;
		//cout << "Blob" << i << ":" << area << endl;
		rect = boundingRect(c);// // 创建包围矩形数据
		rectangle(img, rect, Scalar(0, 0, 0xff), 1);// 调用rectangle()函数在src图像中，把rect包围矩形用红色，1个像素粗细的线框包围起来

		stringstream ss; // 定义字符流变量"ss"，作用是将指定字符串生成输入或输出流
		ss << count;// 将计数数据传递给字符流
		ss >> strCount; // 将字符流中的数据传送给字符串变量
		putText(img, strCount, Point(rect.x, rect.y), CV_FONT_HERSHEY_PLAIN, 0.5, Scalar(0, 0xff, 0));
		// 调用putText函数，在src图像上将strCount字符串输出在矩形框左上角，并定义了字体和字号和颜色
	}
	double Area_average = area / count;
	double area_sqrt = sqrt(Area_average);
	double len_average = len / count;
	double len_aqrt = sqrt(len_average);
	cout << "Area_average" << ":" << area/count << endl;
	cout << "Area_sqrt" << ":" << area_sqrt << endl;
	cout << "Len_average" << ":" << len_average << endl;
	cout << "Len_sqrt" << ":" << len_aqrt << endl;
	imshow("经过分割后的图像", img);  // 显示原始图像的缩放图像
	waitKey(10000);
	return 0;
}